package com.snow.service.comment.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.snow.constant.ErrorConstant;
import com.snow.dao.CommentDao;
import com.snow.exception.SiteException;
import com.snow.pojo.dto.cond.CommentCond;
import com.snow.pojo.model.CommentDomain;
import com.snow.pojo.model.ContentDomain;
import com.snow.service.comment.CommentService;
import com.snow.service.content.ContentService;
import com.snow.utils.ApiResponse;
import com.snow.utils.DateKit;
import com.snow.utils.TaleUtils;
import com.sun.org.apache.xalan.internal.xsltc.runtime.ErrorMessages_it;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.CheckedOutputStream;

/**
 * @Description:
 * @author: snow
 * @Date: 2020-01-30
 **/
@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private CommentDao commentDao;
    @Autowired
    private ContentService contentService;

    private static final ConcurrentHashMap<String,String> STATUS_MAP = new ConcurrentHashMap<>();

    private static final String STATUS_NORMAL = "approved";
    private static final String STATUS_BLANK = "not_audit";

    static {
        STATUS_MAP.put("approved",STATUS_NORMAL);
        STATUS_MAP.put("not_audit",STATUS_BLANK);
    }

    private static Logger logger = LoggerFactory.getLogger(CommentServiceImpl.class);

    /**
     * 添加评论并向端反馈评论的问题
     * @param commentDomain
     */
    @Override
    @Transactional
    @CacheEvict(value = "commentsCache",allEntries = true,beforeInvocation = true)
    public void addComment(CommentDomain commentDomain) {
        String msg = null;
        if(commentDomain == null){
            msg = "评论对象为空";
        }
        if(StringUtils.isBlank(commentDomain.getAuthor())){
            commentDomain.setAuthor("客官未留名");
        }
        if(StringUtils.isNotBlank(commentDomain.getMail()) && !TaleUtils.isEmail(commentDomain.getMail())){
            msg = "您输入的邮箱格式有误！";
        }
        if(StringUtils.isBlank(commentDomain.getContent())){
            msg = "评论内容不能为空！";
        }
        if(commentDomain.getContent().length() <5 || commentDomain.getContent().length() > 1000){
            msg = "评论内容不能低于五个字或超过1000字哦！";
        }
        if(commentDomain.getCid() == null){
            msg = "评论文章cid不能为空";
        }
        if(msg != null){
            throw SiteException.withErrorCode(msg);
        }
        ContentDomain article = contentService.getArticleById(commentDomain.getCid());
        if(article == null){
            throw SiteException.withErrorCode(" article is null");
        }
        commentDomain.setOwnerId(article.getAuthorId());
        commentDomain.setStatus(STATUS_MAP.get(STATUS_BLANK));
        commentDomain.setCreated(DateKit.getCurrentUnixTime());
        commentDao.addComment(commentDomain);
        /**
         * 更新文章的评论数
         */
        Integer cid = commentDomain.getCid();
        Integer count = article.getCommentsNum();
        if(count == null){
            count = 0;
        }
        if(cid != null){
            contentService.updateArticleCommentCount(cid,count);
        }

    }

    /**
     * 删除评论及其子评论更新文章的评论数
     * @param coid
     */
    @Override
    @Transactional
    @CacheEvict(value = "commentsCache",allEntries = true)
    public void deleteCommentByCoid(Integer coid) {
        if (coid == null)
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        /**
         * 如果有子评论删除其所有的子评论
         */
        CommentCond commentCond = new CommentCond();
        commentCond.setParent(coid);
        CommentDomain comment = commentDao.getCommentById(coid);
        Integer cid = comment.getCid();
        if(comment == null)
            throw SiteException.withErrorCode("改评论不存在！");
        List<CommentDomain> childDomments = commentDao.getCommentsByCond(commentCond);
        int count = 0;
        if(childDomments != null && childDomments.size() > 0){
            childDomments.forEach(child->{
                commentDao.deleteCommentById(child.getCoid());
            });
            count = childDomments.size();
        }
        commentDao.deleteCommentById(coid);
        count++;

        ContentDomain article = contentService.getArticleById(cid);
        contentService.updateArticleCommentCount(cid,article.getCommentsNum() - count);
    }

    /**
     * 根据主键标号获取评论
     * @param coid
     * @return
     */

    @Override
    @Cacheable(value="commentsCache",key="'commentByCoid_' + #p0")
    public CommentDomain getCommentByCoid(Integer coid) {
        if(coid == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        return commentDao.getCommentById(coid);
    }

    /**
     * 根据条件获取评论
     * @param commentCond
     * @param pageNum
     * @param size
     * @return
     */
    @Override
    @Cacheable(value="commentsCache",key="'commentsByCond' + #p0")
    public PageInfo<CommentDomain> getCommentsByCond(CommentCond commentCond, Integer pageNum, Integer size) {
        if(commentCond == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        PageHelper.startPage(pageNum,size);
        List<CommentDomain> comments = commentDao.getCommentsByCond(commentCond);
        PageInfo<CommentDomain> pageInfo = new PageInfo<>(comments);
        return pageInfo;
    }

    @Override
    @CacheEvict(value = "commentsCache",allEntries = true)
    public void updateCommentStatus(Integer coid, String status) {
        if(coid == null || StringUtils.isBlank(status)){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        commentDao.updateCommentStatus(coid,status);
    }

    @Override
    @Cacheable(value = "commentsCache",key = "'commetsByCid' + #p0")
    public List<CommentDomain> getCommentsByCid(Integer cid) {
        if(cid == null){
            throw SiteException.withErrorCode(ErrorConstant.Commons.PARAM_IS_EMPTY);
        }
        List<CommentDomain> comments = commentDao.getCommentsByCId(cid);
        return comments;
    }
}
